package com.hc.pokemen.feature_pokemen.presentation.pokemon_list

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hc.pokemen.core.utils.Constants
import com.hc.pokemen.feature_pokemen.domain.entity.PokemonListItem
import com.hc.pokemen.feature_pokemen.domain.repository.PokemonRepository
import com.hc.pokemen.feature_pokemen.domain.util.Resource
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class PokemonListViewModel @Inject constructor(private val repository: PokemonRepository) :
    ViewModel() {

    var state by mutableStateOf(PokemonListScreenState())
        private set

    private var curPage = 0

    private var cacheList: List<PokemonListItem>? = null

    private var job: Job? = null


    var effect = MutableSharedFlow<PokemonListEffect>()

    init {
        loadPokemonList()
    }

    fun onEvent(event: PokemonListScreenEvent) {
        when (event) {
            is PokemonListScreenEvent.ErrorRetryClick -> {
                //TODO 未实现
            }

            is PokemonListScreenEvent.PokemonItemClick -> {
                viewModelScope.launch {
                    effect.emit(PokemonListEffect.GoPokemonDetail(event.name, event.dominantColor))
                }
            }

            is PokemonListScreenEvent.PokemonListLoadMore -> {
                loadPokemonListMore()
            }

            is PokemonListScreenEvent.SearchResultChange -> {
                searchPokemon(event.name)
            }
        }
    }


    private fun searchPokemon(name: String) {
        if (name.isNotEmpty()) {
            if (!state.isSearching) {
                cacheList = state.pokemonList
                val result = state.pokemonList.filter { it.name.contains(name, ignoreCase = true) }
                state = state.copy(isSearching = true, pokemonList = result)
            } else {
                val result = cacheList!!.filter { it.name.contains(name) }
                state = state.copy(pokemonList = result)
            }
        } else {
            if (state.isSearching) {
                state = state.copy(isSearching = false, pokemonList = cacheList!!)
            }
        }
    }

    private fun loadPokemonList() {
        viewModelScope.launch {
            when (val resource =
                repository.getPokemonList(Constants.PAGE_SIZE, Constants.PAGE_SIZE * curPage)) {
                is Resource.Error -> {

                }

                is Resource.Success -> {
                    val temp = resource.data?.items ?: emptyList()
                    state = state.copy(pokemonList = temp)
                    curPage++
                }
            }
        }
    }


    private fun loadPokemonListMore() {
//        if (curPage == 3) {
//            state = state.copy(endReached = true)
//            return
//        }
        job?.cancel()
        job = viewModelScope.launch {
            when (val resource =
                repository.getPokemonList(Constants.PAGE_SIZE, Constants.PAGE_SIZE * curPage)) {
                is Resource.Error -> {

                }

                is Resource.Success -> {
                    val append = resource.data?.items ?: emptyList()
                    curPage++
                    if (append.isNotEmpty()) {
                        val temp = state.pokemonList + append
                        state = state.copy(pokemonList = temp)
                    }
                }
            }
        }
    }
}